using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
using Random = UnityEngine.Random;

public class BoardManager : MonoBehaviour
{
    public int Width = 8;
    public int Height = 8;
    public Tile[] GroundTiles;
    public Tile[] WallTiles;

    [SerializeField, Utility.Attributes.NotNull]
    private FoodObject m_FoodPrefab;

    [Header("Food data")] 
    [SerializeField, Utility.Attributes.NotNull] private FoodData m_smallFood;
    [SerializeField, Utility.Attributes.NotNull] private FoodData m_bigFood;
    
    

    private Tilemap _tilemap;
    private Grid m_Grid;
    private CellData[,] _boardData;
    private List<Vector2Int> m_emptyCellList;
    
    public class CellData
    {
        public bool Passable;
        public CellObject ContainedObject;
    }

    void Awake()
    {
        _tilemap = GetComponentInChildren<Tilemap>();
        m_Grid = GetComponentInChildren<Grid>();
        _boardData = new CellData[Height,Width];
        m_emptyCellList = new List<Vector2Int>();
    }
    
    public Vector3 CellToWorld(Vector2Int cellIndex)
    {
        return m_Grid.GetCellCenterWorld((Vector3Int)cellIndex);
    }

    public bool IsThisCellMovealbe(Vector2Int tryToMoveCell) {
        return IsThisCellAvailable(tryToMoveCell) && _boardData[tryToMoveCell.x, tryToMoveCell.y].Passable;
    }

    public bool TryGetCellData(Vector2Int cellIndex, out CellData cellData) {
        if (IsThisCellAvailable(cellIndex)) {
            cellData = _boardData[cellIndex.x, cellIndex.y];
            return true;
        }

        cellData = null;
        return false;
    }

    private bool IsThisCellAvailable(Vector2Int cellToCheck) {
        if (cellToCheck.x < Width && cellToCheck.x > 0) {
            return true;
        }

        return cellToCheck.y < Height && cellToCheck.y > 0;
    }

    public void Init() {
        generateGround();
        generateFood();
    }
    
    void generateFood() {
        var ints = RandomUtils.GetRandomUniqueInts(5, 1, m_emptyCellList.Count);
        foreach (var index in ints) {
            var point = m_emptyCellList[index];
            var cellData = _boardData[point.x, point.y];
            var newFood = Instantiate<FoodObject>(m_FoodPrefab);
            int b = Random.Range(1, 11);
            Sprite sprite;
            int amount;
            if (b > 9) {
                sprite = m_bigFood.FoodSprite;
                amount = Random.Range(m_bigFood.MinFoodAmount, m_bigFood.MinFoodAmount);
            }
            else {
                sprite = m_smallFood.FoodSprite;
                amount = Random.Range(m_smallFood.MinFoodAmount, m_smallFood.MinFoodAmount);
            }
            
            newFood.GetComponent<SpriteRenderer>().sprite = sprite;
            newFood.transform.position = CellToWorld(point);
            newFood.Init(true, amount);
            cellData.ContainedObject = newFood;
        }
    }

    void generateGround()
    {
        Tile tile = null;
        
        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                _boardData[x, y] = new CellData();
                if (x == 0 || y == 0 || x == Width - 1 || y == Height - 1)
                {
                    tile = WallTiles[Random.Range(0, WallTiles.Length)];
                    _boardData[x,y].Passable = false;
                }
                else
                {
                    tile = GroundTiles[Random.Range(0, GroundTiles.Length)];
                    _boardData[x, y].Passable = true;
                    m_emptyCellList.Add(new Vector2Int(x, y));
                }
                _tilemap.SetTile(new Vector3Int(x,y,0), tile);
            }
        }
        m_emptyCellList.Remove(new Vector2Int(1,1));
    }
}
